package org.oimwrapper.connectors.common;

import java.util.*;

import org.oimwrapper.connectors.*;
import org.oimwrapper.connectors.adapters.*;

/**
 * Updates all resource instances provisioned via access policy to have the proper 
 * links from the form data back to the policy and the revoke if no longer applies 
 * flag to ensure that resource revocation is handled correctly.<p>
 *
 * This task expects the following parameters, in addition to the standard
 * parameters in the {@link OIMTaskBase} class.
 * <ul>
 * <li><code>Threads</code> The number of threads to use to process resource instances. 
 *                          Setting this to 1 will disabled threading.</li>
 * </ul>
 */
public class OIMSetFlagsForPolicyResources extends OIMTaskBase {
	
	/**
	 * True if a stop has been requested for this task.
	 */
	private boolean stop;

	/**
	 * Default constructor.
	 */
	public OIMSetFlagsForPolicyResources() {
		super("OIMWRAPPER.TASK");
		stop = false;
	}
	
	/**
	 * Constructor to specify the log category.
	 * 
	 * @param LogCategory The log category to use.
	 */
	public OIMSetFlagsForPolicyResources(String LogCategory) {
		super(LogCategory);
		stop = false;
	}

	/**
	 * This method is called by the scheduler to execute the task instance.
	 */
	public void execute() {
		logger.debug("Entering setFlagsForPolicyResources.execute()");
		try {
			OIMPolicyFlagChecker checker = new OIMPolicyFlagChecker(this);
			int maxWorkers = Integer.parseInt(getDefaultAttribute("Threads", "10"));
			Map[] resources = checker.getResourceDetails();
			for (int i = 0; !stop && i < resources.length; i++) {
				logger.info("Processing Resource Instance " + Integer.toString(i + 1) + " of " + Integer.toString(resources.length));
				startThread(maxWorkers, new worker(this, checker, resources[i]));
			}
			waitForAllThreads();
		} catch (Exception e) {
			OIMExceptionHandler.handleException(logger, e, getClass());
		}
		logger.debug("Exiting setFlagsForPolicyResources.execute()");
	}

	/**
	 * This method is called by the scheduler to stop a running task instance.
	 * 
	 * @return <code>true</code>
	 */
	public boolean stop() {
		logger.debug("Entering setFlagsForPolicyResources.stop()");
		logger.warn(" ---- Stopping current task ---- ");
		stop = true;
		logger.debug("Exiting setFlagsForPolicyResources.stop()");
		return stop;
	}
	
	/**
	 * Worker Thread.
	 */
	private class worker extends OIMTaskThreadBase {
		
		/**
		 * The policy flag checker to use.
		 */
		private OIMPolicyFlagChecker checker;
		
		/**
		 * The resource instance data of the record to process.
		 */
		private Map resourceData;
		
		/**
		 * Default Constructor.
		 * 
		 * @param Task The calling task.
		 * @param Checker The policy flag checker to use.
		 * @param ResourceData The resource instance data of the record to process.
		 */
		private worker(OIMSetFlagsForPolicyResources Task, OIMPolicyFlagChecker Checker, Map ResourceData) {
			super(Task);
			checker = Checker;
			resourceData = ResourceData;
		}
		
		/**
		 * Processes a single resource instance.
		 */
		public void runOimThread() {
			try {
				checker.processSingleInstance(resourceData);
			} catch (Exception e) {
				OIMExceptionHandler.handleException(logger, e, getClass());
			}
		}
	}
}